﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace Hidden_Picture
{
    static class PictureIO
    {
        public static int R = 299;
        public static int G = 587;
        public static int B = 114;
        public static System.Drawing.Drawing2D.InterpolationMode interpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
        public static int FinalWidth;
        public static int FinalHeight;
        public static ColorMode colorMode = ColorMode.GRAY;
        public static int total;
        public static int progress;
        public enum ColorMode
        {
            GRAY,
            BLACK_AND_WHITE,
            COLORFUL
        }
        public static Bitmap GetBitmap()
        {
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "图片|*.jpg;*.png;*.bmp|所有文件|*.*";
            if(open.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    return new Bitmap(open.FileName);
                }
                catch(Exception ex)
                {
                    ShowException(ex);
                }
            }
            return null;
        }

        private static Bitmap Scale(Bitmap b,int width,int height)
        {
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            g.InterpolationMode = interpolationMode;
            g.DrawImage(b, new Rectangle(0, 0, width, height), new Rectangle(0, 0, b.Width, b.Height), GraphicsUnit.Pixel);
            g.Dispose();
            return bitmap;
        }

        public static Bitmap GetResult(Bitmap bitmap1,Bitmap bitmap2)
        {
            Bitmap p1 = null, p2 = null;
            progress = 0;
            try
            {
                if(bitmap1.Width != FinalWidth || bitmap1.Height != FinalHeight)
                {
                    p1 = Scale(bitmap1, FinalWidth, FinalHeight);
                }
                if (bitmap2.Width != FinalWidth || bitmap2.Height != FinalHeight)
                {
                    p2 = Scale(bitmap2, FinalWidth, FinalHeight);
                }
                switch (colorMode)
                {
                    case ColorMode.BLACK_AND_WHITE:
                        return Merge_BLACK_AND_WHITE(p1 == null ? bitmap1 : p1, p2 == null ? bitmap2 : p2);
                    case ColorMode.COLORFUL:
                        return Merge_COLORFUL(p1 == null ? bitmap1 : p1, p2 == null ? bitmap2 : p2);
                    case ColorMode.GRAY:
                    default:
                        return Merge_GRAY(p1 == null ? bitmap1 : p1, p2 == null ? bitmap2 : p2);
                }
            }
            catch(Exception ex)
            {
                ShowException(ex);
                Form1.wait.close();
                return null;
            }
            finally
            {
                if (p1 != null) p1.Dispose();
                if (p2 != null) p2.Dispose();
            }
        }

        

        private static Bitmap Merge_COLORFUL(Bitmap p1,Bitmap p2)
        {
            bool flag;
            Color color;
            int transparency;
            Bitmap bitmap = new Bitmap(p1.Width, p1.Height);
            total = p1.Width * p1.Height;
            for (int i = 0; i < p1.Width; i++)
            {
                for (int j = 0; j < p1.Height; j++)
                {
                    flag = (i + j) % 2 == 0;
                    if (flag)
                    {
                        color = p1.GetPixel(i, j);
                        transparency = (color.R * R + color.G * G +  color.B * B) / 1000;
                        bitmap.SetPixel(i, j, Color.FromArgb(255 - transparency, p1.GetPixel(i, j)));
                    }
                    else
                    {
                        color = p2.GetPixel(i, j);
                        transparency = (color.R * R + color.G * G + color.B * B) / 1000;
                        bitmap.SetPixel(i, j, Color.FromArgb(transparency, p2.GetPixel(i,j)));
                    }
                    progress++;
                }
            }
            return bitmap;
        }
        private static Bitmap Merge_GRAY(Bitmap p1, Bitmap p2)
        {
            bool flag;
            Color color;
            int transparency;
            Bitmap bitmap = new Bitmap(p1.Width, p1.Height);
            total = p1.Width * p1.Height;
            for (int i = 0; i < p1.Width; i++)
            {
                for (int j = 0; j < p1.Height; j++)
                {
                    flag = (i + j) % 2 == 0;
                    if (flag)
                    {
                        color = p1.GetPixel(i, j);
                        transparency = (color.R * R + color.G * G + color.B * B) / 1000;
                        bitmap.SetPixel(i, j, Color.FromArgb(255 - transparency, Color.Black));
                    }
                    else
                    {
                        color = p2.GetPixel(i, j);
                        transparency = (color.R * R + color.G * G + color.B * B) / 1000;
                        bitmap.SetPixel(i, j, Color.FromArgb(transparency, Color.White));
                    }
                    progress++;
                }
            }
            return bitmap;
        }
        private static Bitmap Merge_BLACK_AND_WHITE(Bitmap p1, Bitmap p2)
        {
            bool flag;
            Color color;
            int RGB;
            Bitmap bitmap = new Bitmap(p1.Width, p1.Height);
            total = 2 * p1.Width * p1.Height;
            int[,] gray1 = new int[p1.Width,p1.Height];
            int[,] gray2 = new int[p1.Width, p1.Height];
            int sum1 = 0, sum2 = 0;
            for (int i = 0; i < p1.Width; i++)
            {
                for (int j = 0; j < p1.Height; j++)
                {
                    color = p1.GetPixel(i,j);
                    gray1[i, j] = (color.R * R + color.G * G + color.B * B) / 1000;
                    sum1 += gray1[i, j];
                    color = p2.GetPixel(i, j);
                    gray2[i, j] = (color.R * R + color.G * G + color.B * B) / 1000;
                    sum2 += gray2[i, j];
                    progress++;
                }
            }
            sum1 /= p1.Width * p1.Height;
            sum2 /= p1.Width * p1.Height;
            for(int i = 0; i < p1.Width; i++)
            {
                for(int j = 0; j < p1.Height; j++)
                {
                    flag = (i + j) % 2 == 0;
                    if (flag)
                    {
                        RGB = gray1[i, j] > sum1 ? 0 : 255;
                        bitmap.SetPixel(i, j, Color.FromArgb(RGB, Color.Black));
                    }
                    else
                    {
                        RGB = gray2[i, j] > sum2 ? 0 : 255;
                        bitmap.SetPixel(i, j, Color.FromArgb(255 - RGB, Color.White));
                    }
                    progress++;
                }
            }
            return bitmap;
        }
        public static void ShowException(Exception ex)
        {
            MessageBox.Show(Form1.wait,ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}
